﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Pg.BioMedics.SDR.Data;
using Pg.BioMedics.SDR.Entities;
using Pg.BioMedics.SDR.Entities.Codes;
using Pg.BioMedics.SDR.Caching;

namespace Pg.BioMedics.SDR.Data.Caching
{
    /// <summary>
    /// Provides an entry point for Annotation and related entities access. This provider 
    /// adds cachning support for the base AnnotationManager.
    /// </summary>
    internal sealed class CachedAnnotationManager : AnnotationManager
    {
        #region Constructors

        /// <summary>
        /// Creates instance of CachedannotationManager. Provdes initialization of the base
        /// data manager
        /// </summary>
        /// <param name="dataMapperStrategy">Data mapper strategy used for ORM purposes</param>
        internal CachedAnnotationManager(IDataMapperStrategy dataMapperStrategy)
            : base(dataMapperStrategy) { }

        #endregion

        #region Overriden methods

        public override Annotation InsertAnnotation(Annotation annotation)
        {
            annotation = base.InsertAnnotation(annotation);

            SDRCacheContext.Instance.AnnotationCache.Put(annotation);
            return annotation;
        }

        public override void SetAnnotationStatus(Annotation annotation, string statusCode, Person author)
        {
            base.SetAnnotationStatus(annotation, statusCode, author);

            annotation.StatusCode = statusCode;
            annotation.StatusDate = DateTime.Now;
            SDRCacheContext.Instance.AnnotationCache.Put(annotation);            
        }

        public override Annotation GetAnnotationById(int annotationId)
        {
            Annotation selectedAnnotation = (from annotation in SDRCacheContext.Instance.AnnotationCache.Query
                                             where annotation.Id == annotationId
                                             select annotation).FirstOrDefault();

            return base.GetAnnotationById(annotationId);
        }

        public override Annotation GetAnnotationByAsrTaskUniqueId(Guid asrTaskUniqueId)
        {
            return base.GetAnnotationByAsrTaskUniqueId(asrTaskUniqueId);
        }

        public override IList<Annotation> GetAnnotationsByDocument(Document document)
        {
            return base.GetAnnotationsByDocument(document);
        }

        public override void UpdateAnnotation(Annotation annotation)
        {
            base.UpdateAnnotation(annotation);
            SDRCacheContext.Instance.AnnotationCache.Put(annotation);
        }

        /// <summary>
        /// Inserts a new token into the database
        /// </summary>
        /// <param name="token">Token entity</param>
        /// <returns>Saved token</returns>
        public override Token InsertToken(Token token)
        {
            token = base.InsertToken(token);

            SDRCacheContext.Instance.TokenCache.Put(token);
            return token;
        }

        /// <summary>
        /// Gets token by its unique id
        /// </summary>
        /// <param name="tokenId">Token unique id</param>
        /// <returns>Token instance</returns>
        public override Token GetTokenById(int tokenId)
        {
            return base.GetTokenById(tokenId);
        }

        /// <summary>
        /// Gets tokens holded by the given annotation. This method looks up cache first. If 
        /// result doesnot exist in the cache it is being retrived from the database and updated in the cache.
        /// </summary>
        /// <param name="annotation">Document annotation</param>
        /// <returns>List of tokens from given annotation</returns>
        public override IList<Token> GetTokensByAnnotation(Annotation annotation)
        {
            return base.GetTokensByAnnotation(annotation);
        }

        #endregion
    }
}
